//share_ptr
#if 1
#include <iostream>
#include <memory>
using namespace std;
class Test
{
public:
    Test(string s)
    {
        str = s;
        cout << "Test create" << endl;
    }
    ~Test()
    {
        cout << "Test delete:" << str << endl;
    }
    string &get_str()
    {
        return str;
    }
    void set_str(string s)
    {
        str = s;
    }
    void print()
    {
        cout << str << endl;
    }

private:
    string str;
};

unique_ptr<Test> fun()
{
    return unique_ptr<Test>(new Test("789"));
}

int main()
{
    shared_ptr<Test> ptest(new Test("123")); //构造
    shared_ptr<Test> ptest2(new Test("456"));
    cout << "ptest2 value : " << ptest2->get_str() << endl; //456
    //显示此资源被几个指针共享,输出1
    cout << "ptest2 count : " << ptest2.use_count() << endl;
    //456引用次数加1,123销毁,
    //输出Test delete:123
    ptest = ptest2;
    ptest->print(); //456

    //该指针指向的资源被几个指针共享,输出2
    //该指针指向的资源是456,456被ptest,ptest2,顾输出2
    cout << "ptest2 count : " << ptest2.use_count() << endl;
    cout << "ptest  count :" << ptest.use_count() << endl;

    //重新绑定对象,绑定一个空对象
    //此时指针指向的对象还有其他指针指向,就不释放该内存空间,456引用-1
    ptest.reset();
    cout << "ptest  count :" << ptest2.use_count() << endl;
    //此时456销毁,此时指针指向的内存空间上的指针为0,就释放该内存,
    //输出Test delete
    ptest2.reset();

    cout << "done!" << endl;
    cout << "ptest2 count : " << ptest2.use_count() << endl;
    cout << "ptest  count :" << ptest.use_count() << endl;

    {
        cout << "-------------make_shared ---------- " << endl;

        shared_ptr<Test> pt1 = make_shared<Test>("pt1-value");
        shared_ptr<Test> pt2 = make_shared<Test>("pt2-value");

        cout << "pt1 value : " << pt1->get_str() << " count :　" << pt1.use_count() << endl;  //pt1-value
        cout << "pt2 value :  " << pt2->get_str() << " count :　" << pt2.use_count() << endl; //pt2-value

        pt2 = pt1;
        cout << "pt1 value : " << pt1->get_str() << " count :　" << pt1.use_count() << endl;  //pt1-value
        cout << "pt2 value :  " << pt2->get_str() << " count :　" << pt2.use_count() << endl; //pt1-value
    }

    return 0;
}

#endif